﻿using System;
using System.Collections.Generic;
using System.Linq;
using TeF.Runner.Helpers;

namespace TeF.Runner
{
    internal class TestContainer : TestStateEntityBase, ITestContainer, ITestEntityChildOfT<TestNamespace, TestContainer>, ITestEntityParentOfT<TestContainer, Test>
    {
        #region Fields

        private readonly TestParentHelper<TestContainer, Test> _testParentHelper;
        
        #endregion


        #region Constructors

        public TestContainer(Type type, bool ignored, TestNamespace testNamespace, TestContainerSetUp setUp, TestContainerTearDown tearDown)
            : base(ignored)
        {
            if (type == null)
                throw new ArgumentNullException("type");
            if (testNamespace == null)
                throw new ArgumentNullException("testNamespace");

            Type = type;

            Parent = testNamespace;

            SetUp = setUp;
            TearDown = tearDown;

            _testParentHelper = new TestParentHelper<TestContainer, Test>(this);
        }
        
        #endregion


        #region Properties
        
        public Type Type { get; private set; }
        public TestContainerSetUp SetUp { get; private set; }
        public TestContainerTearDown TearDown { get; private set; }
        
        public override string Name
        {
            get { return Type.Name; }
        }

        public TestNamespace Parent { get; private set; }

        public ITestNamespace Namespace
        {
            get { return Parent; }
        }

        public IEnumerable<ITest> Tests
        {
            get { return _testParentHelper.Children; }
        }

        public IEnumerable<Test> Children
        {
            get { return _testParentHelper.Children; }
        }
        
        #endregion


        #region Public Methods

        public void AddChild(Test child)
        {
            _testParentHelper.AddChild(child);
        }

        public void Dispose()
        {
            _testParentHelper.Dispose();
        }

        public IEnumerable<Test> GetTestsToRun()
        {
            if (Ignored)
                return new Test[] { };

            return
                _testParentHelper.Children
                    .Where(c => !c.Ignored);
        }

        #endregion
    }
}
